import { Context } from "koa";
import { DishService } from "../services/dishes.service";
import { CreateDishDTO } from "../dtos/dishes.dto";
import {
  CreateDishesRequestDTO,
  UpdateDishesRequestDTO,
} from "../validators/dishes.validator";
import { CategoryIdDTO, IdDTO } from "../validators/request.validator";
import { AuthUtil, TokenPayload } from "../utils/auth.util";

/**
 * 菜品控制器
 */
export class DishController {
  /**
   * 新增菜品
   */
  public static async createDish(ctx: Context): Promise<void> {
    try {
      // 从请求体获取数据
      // const dishData = (ctx.request as any).body as CreateDishesRequestDTO;
      const dishData = ctx.state.validatedBody as CreateDishesRequestDTO;

      // 调用服务创建菜品
      const newDish = await DishService.createDish(dishData);

      // 返回成功响应
      ctx.status = 201;
      ctx.body = {
        code: 201,
        message: "菜品创建成功",
        data: newDish,
      };
    } catch (error) {
      console.error("创建菜品失败:", error);

      ctx.status = 500;
      ctx.body = {
        code: 500,
        message: error instanceof Error ? error.message : "创建菜品失败",
      };
    }
  }

  /**
   * 获取所有菜品
   */
  public static async listAll(ctx: Context): Promise<void> {
    try {
      // 从token中获取用户id
      const tokenPayload = AuthUtil.getTokenPayLoad(ctx);

      let dishes;
      if (tokenPayload) {
        // 如果携带token则返回的菜品中包含isWished字段，值为true表示用户下周想吃
        dishes = await DishService.listAllWithIsWished(tokenPayload.userId);
      } else {
        // 否则返回普通的菜品列表
        dishes = await DishService.listAll();
      }

      ctx.status = 200;
      ctx.body = {
        code: 200,
        message: "成功获取菜品列表",
        data: dishes,
      };
    } catch (error) {
      console.error("获取菜品失败:", error);
      ctx.status = 500;
      ctx.body = {
        code: 500,
        message: error instanceof Error ? error.message : "服务器内部错误",
      };
    }
  }

  /**
   * 获取单个菜品详情
   */
  public static async getDishById(ctx: Context): Promise<void> {
    try {
      const { id } = ctx.state.validatedParams as IdDTO;
      const dishes = await DishService.getDishById(id);

      if (!dishes) {
        ctx.status = 404;
        ctx.body = { code: 404, message: "菜品不存在" };
        return;
      }

      ctx.status = 200;
      ctx.body = { code: 200, data: dishes };
    } catch (error) {
      console.error("获取菜品失败:", error);
      ctx.status = 500;
      ctx.body = { code: 500, message: "服务器内部错误" };
    }
  }

  /**
   * 根据菜品分类id查询菜品，
   * 如果携带token则返回的菜品中包含isWished字段，值为true表示用户下周想吃
   */
  public static async getDishesByCategoryId(ctx: Context): Promise<void> {
    try {
      const { categoryId } = ctx.state.validatedParams as CategoryIdDTO;
      const tokenPayload = AuthUtil.getTokenPayLoad(ctx);

      let dishes;
      if (tokenPayload) {
        dishes = await DishService.getDishesWithIsWishedByCategoryId(
          categoryId,
          tokenPayload.userId
        );
      } else {
        dishes = await DishService.getDishesByCategoryId(categoryId);
      }

      ctx.status = 200;
      ctx.body = { code: 200, data: dishes };
    } catch (error) {
      console.error("获取菜品失败:", error);
      ctx.status = 500;
      ctx.body = { code: 500, message: "服务器内部错误" };
    }
  }

  /**
   * 更新菜品
   */
  public static async updateDish(ctx: Context): Promise<void> {
    try {
      const { id } = ctx.state.validatedParams as IdDTO;
      const dishData = ctx.state.validatedBody as UpdateDishesRequestDTO;

      const updatedDish = await DishService.updateDish(id, dishData);

      if (!updatedDish) {
        ctx.status = 404;
        ctx.body = { code: 404, message: "菜品不存在" };
        return;
      }

      ctx.status = 200;
      ctx.body = { code: 200, message: "菜品更新成功", data: updatedDish };
    } catch (error) {
      console.error("更新菜品失败:", error);
      ctx.status = 500;
      ctx.body = { code: 500, message: "服务器内部错误" };
    }
  }

  /**
   * 删除菜品
   */
  public static async deleteDish(ctx: Context): Promise<void> {
    try {
      const { id } = ctx.state.validatedParams as IdDTO;
      await DishService.deleteDish(id);
      ctx.status = 204;
    } catch (error) {
      console.error("删除菜品失败:", error);
      ctx.status = 500;
      ctx.body = { code: 500, message: "服务器内部错误" };
    }
  }

  /**
   * 菜品评分
   */
  public static async rateDish(ctx: Context): Promise<void> {
    try {
      const { id } = ctx.state.validatedParams as IdDTO;
      const { score } = ctx.state.validatedBody as { score: number };
      const { userId } = ctx.state.authorization as TokenPayload;

      await DishService.rateDish(id, score, userId);
      ctx.status = 200;
      ctx.body = { code: 200, message: "评分成功" };
    } catch (error) {
      console.error("评分失败:", error);
      ctx.status = 500;
      ctx.body = {
        code: 500,
        message: error instanceof Error ? error.message : "服务器内部错误",
      };
    }
  }
}
